<template>
  <div class="chat-container">
    <!-- 左侧会话列表 -->
    <div :class="['session-list', { disabled: aiTyping || aiGenerating }]">
      <div :class="['new-chat', { disabled: aiTyping || aiGenerating }]">
        <el-button type="primary" plain block @click="createNewSession" :disabled="aiTyping || aiGenerating">
          <i class="el-icon-plus"></i>
          新建会话
        </el-button>
      </div>
      <div class="session-items" v-loading="loading">
        <div v-for="(item, index) in sessionList" 
             :key="item.id" 
             :class="['session-item', { active: currentSession === index }]"
             @click="handleSessionClick(index)">
          <div class="session-content" >
            <i class="el-icon-chat-line-round"></i>
            <span>{{ item.title }}</span>
          </div>
          <div class="session-actions" v-show="currentSession === index">
            <el-tooltip content="编辑标题" placement="top">
              <i class="el-icon-edit-outline" @click.stop="handleSessionAction(() => editSession(item))"></i>
            </el-tooltip>
            <el-tooltip content="删除会话" placement="top">
              <i class="el-icon-delete" @click.stop="handleSessionAction(() => handleDelete(item))"></i>
            </el-tooltip>
          </div>
        </div>
      </div>
    </div>

    <!-- 右侧聊天区域 -->
    <div class="chat-main">
      <div class="chat-messages" ref="messageContainer">
        <!-- 无消息时的提示 -->
        <div v-if="!messages.length && !loading" class="empty-message">
          <img src="@/assets/logo/logo512.png" class="logo" alt="JHM Logo">
          <h3>我是JHM，你的个人AI助手</h3>
          <p>请在下面输入消息和我聊天吧~</p>
        </div>
        
        <div v-else v-for="(msg, index) in messages" 
             :key="index" 
             :class="['message-item', msg.role]">
          <div class="avatar">
            <el-avatar :size="40" :src="msg.role === 'user' ? userAvatar : require('@/assets/logo/logo.png')"></el-avatar>
          </div>
          <div class="message-box">
            <div class="message-content">
              <template v-if="msg.role === 'user'">
                {{ msg.message }}
              </template>
              <v-md-preview v-else :text="transformMessage(msg.message)"></v-md-preview>
            </div>
            <div class="message-actions" v-if="msg.role === 'assistant' && msg.message">
              <el-tooltip content="复制" placement="top">
                <el-button type="text" size="mini" @click="copyMessage(msg.message)">
                  <i class="el-icon-document-copy"></i>
                </el-button>
              </el-tooltip>
              <el-tooltip content="重新生成" placement="top">
                <el-button type="text" size="mini" @click="regenerateMessage(index)">
                  <i class="el-icon-refresh"></i>
                </el-button>
              </el-tooltip>
            </div>
          </div>
        </div>
        <!-- AI 思考中的效果 -->
        <div v-if="aiTyping && !aiGenerating" class="message-item assistant">
          <div class="avatar">
            <el-avatar :size="40" :src="require('@/assets/logo/logo.png')"></el-avatar>
          </div>
          <div class="message-box">
            <div class="message-content thinking">
              <i class="el-icon-loading"></i>
              <span class="thinking-text">思考中</span>
            </div>
          </div>
        </div>
        <!-- AI 生成中的提示 -->
        <div v-if="aiGenerating" class="generating-status">
          <i class="el-icon-loading"></i>
          <span>生成中...</span>
        </div>
      </div>
      <div class="chat-input">
        <div class="input-actions">
          <el-upload
            action="#"
            :show-file-list="false"
            :disabled="aiTyping || aiGenerating"
            :before-upload="handleFileUpload">
            <el-tooltip content="上传附件" placement="top">
              <el-button size="small" icon="el-icon-paperclip" :disabled="aiTyping || aiGenerating"></el-button>
            </el-tooltip>
          </el-upload>
        </div>
        <el-input
          v-model="inputMessage"
          type="textarea"
          autosize
          :rows="1"
          :disabled="aiTyping || aiGenerating"
          placeholder="Enter 发送，Shift + Enter 换行"
          @keyup.enter.native.prevent="handleEnterPress"
          @keydown.native="handleKeyDown"
        ></el-input>
        <el-button 
          :type="aiTyping || aiGenerating ? 'danger' : 'primary'" 
          :class="{ 'stop-button': aiTyping || aiGenerating }"
          :icon="aiTyping || aiGenerating ? 'el-icon-close' : 'el-icon-position'" 
          :title="aiTyping || aiGenerating ? '停止生成' : '发送'"
          @click="aiTyping || aiGenerating ? stopGeneration() : sendMessage()">
        </el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { listSessions, createSession, updateSession, deleteSession, getSessionMessages, getRequestId, stopGeneration } from "@/api/ai/chat";
import { sseRequest } from '@/utils/sseRequest'

export default {
  name: 'Chat',
  directives: {
    focus: {
      inserted: function(el) {
        el.querySelector('input').focus()
      }
    }
  },
  computed: {
    ...mapGetters([
      'avatar'
    ]),
    userAvatar() {
      return this.avatar
    }
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      inputMessage: '',
      currentSession: 0,
      sessionList: [],
      messages: [],
      // 是否显示编辑标题弹窗
      editDialogVisible: false,
      // 编辑的会话信息
      editForm: {
        id: undefined,
        title: ''
      },
      currentEventSource: null,
      abortController: null,
      aiTyping: false,
      aiGenerating: false, // 控制生成中状态
      currentRequestId: null
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /** 查询会话列表 */
    getList() {
      this.loading = true
      listSessions().then(response => {
        this.sessionList = response.data
        this.loading = false
        // 如果没有会话，自动创建一个
        if (!this.sessionList.length) {
          this.createNewSession()
        } else {
          // 默认选中第一个会话并加载消息
          this.switchSession(0)
        }
      })
    },
    /** 创建新会话 */
    createNewSession() {
      createSession({ title: '新会话' }).then(response => {
        this.$modal.msgSuccess("创建成功")
        this.getList()
      })
    },
    /** 编辑会话标题 */
    editSession(row) {
      this.$prompt('请输入会话标题', '修改标题', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputValue: row.title,
        inputValidator: (value) => {
          return value.trim().length > 0
        },
        inputErrorMessage: '标题不能为空'
      }).then(({ value }) => {
        updateSession({
          id: row.id,
          title: value.trim()
        }).then(() => {
          this.$modal.msgSuccess("修改成功")
          this.getList()
        })
      }).catch(() => {})
    },
    /** 删除会话 */
    handleDelete(row) {
      this.$modal.confirm('是否确认删除该会话？').then(function() {
        return deleteSession(row.id)
      }).then(() => {
        this.getList()
        this.$modal.msgSuccess("删除成功")
      }).catch(() => {})
    },
    /** 切换会话 */
    switchSession(index) {
      this.currentSession = index
      this.loadSessionMessages(this.sessionList[index].id)
    },
    /** 加载会话消息 */
    loadSessionMessages(sessionId) {
      getSessionMessages(sessionId).then(response => {
        this.messages = response.data
        this.$nextTick(() => {
          this.scrollToBottom()
        })
      })
    },
    // 复制消息内容
    copyMessage(text) {
      navigator.clipboard.writeText(text).then(() => {
        this.$message.success('复制成功')
      }).catch(() => {
        this.$message.error('复制失败')
      })
    },

    // 重新生成消息
    regenerateMessage(index) {
      if (this.aiTyping) return
      const messages = this.messages.slice(0, index)
      const lastUserMessage = messages.filter(m => m.role === 'user').pop()
      if (lastUserMessage) {
        this.messages = messages
        this.sendMessage(lastUserMessage.message)
      }
    },

    /** 发送消息 */
    async sendMessage(customMessage) {
      if ((!this.inputMessage.trim() && !customMessage) || this.aiTyping) return
      
      const userMessage = customMessage || this.inputMessage.trim()
      const sessionId = this.sessionList[this.currentSession].id

      // 添加用户消息
      this.messages.push({
        role: 'user',
        message: userMessage
      })
      
      this.inputMessage = ''
      this.aiTyping = true
      
      this.$nextTick(() => {
        this.scrollToBottom()
      })

      try {
        // 获取新的requestId
        const res = await getRequestId()
        this.currentRequestId = res.data

        // 创建新的 AbortController
        this.abortController = new AbortController()

        // 发起SSE请求
        sseRequest('/ai/chat/sse',
          {
            query: userMessage,
            sessionId: sessionId.toString(),
            requestId: this.currentRequestId
          },
          (data) => {
            if (data.content && !this.aiGenerating) {
              this.aiGenerating = true
              this.aiTyping = false
              this.messages.push({
                role: 'assistant',
                message: ''
              })
            }
            // 处理消息
            if (data.content) {
              this.messages[this.messages.length - 1].message += data.content
              this.$nextTick(() => {
                this.scrollToBottom()
              })
            }
            // 处理错误
            if (data.error) {
              this.$modal.msgError(data.error || '服务器繁忙，请稍后重试')
              this.aiTyping = false
              this.aiGenerating = false
              return
            }
            // 检查是否结束
            if (data.type === 'done') {
              this.aiTyping = false
              this.aiGenerating = false
              this.currentRequestId = null
            }
          },
          (error) => {
            if (error.name === 'AbortError') {
              console.log('请求被中止')
            } else {
              console.error('SSE error:', error)
              this.$modal.msgError('服务器连接失败，请稍后重试')
            }
            this.aiTyping = false
            this.aiGenerating = false
          },
          this.abortController.signal,
          (status) => {
            // 请求完成的回调，无论是正常完成还是被中止
            this.aiTyping = false
            this.aiGenerating = false
            // 重新加载消息列表以确保获取最新状态
            if (status === 'aborted') {
              this.loadSessionMessages(sessionId)
            }
          }
        )
      } catch (error) {
        console.error('获取requestId失败:', error)
        this.$modal.msgError('服务器连接失败，请稍后重试')
        this.aiTyping = false
        this.aiGenerating = false
      }
    },
    scrollToBottom() {
      const container = this.$refs.messageContainer
      container.scrollTop = container.scrollHeight
    },
    handleFileUpload(file) {
      const isLt10M = file.size / 1024 / 1024 < 10;
      if (!isLt10M) {
        this.$message.error('上传文件大小不能超过 10MB!');
        return false;
      }
      // 处理文件上传
      console.log('上传文件:', file)
      return false // 阻止默认上传行为
    },
    handleEnterPress(e) {
      if (!e.shiftKey) {
        this.sendMessage()
      }
    },
    handleKeyDown(e) {
      if (e.keyCode === 13 && e.shiftKey) {
        // Shift + Enter 换行
        e.preventDefault()
        const textArea = e.target
        const start = textArea.selectionStart
        const end = textArea.selectionEnd
        this.inputMessage = this.inputMessage.substring(0, start) + '\n' + this.inputMessage.substring(end)
        this.$nextTick(() => {
          textArea.selectionStart = textArea.selectionEnd = start + 1
        })
      }
    },
    /** 停止生成 */
    async stopGeneration() {
      if (this.currentRequestId) {
        try {
          await stopGeneration(this.currentRequestId)
        } catch (error) {
          console.error('停止生成失败:', error)
        }
      }
      
      if (this.abortController) {
        this.abortController.abort()
        this.abortController = null
      }
      
      this.currentRequestId = null
      this.aiTyping = false
      this.aiGenerating = false
    },
    /** 处理会话点击 */
    handleSessionClick(index) {
      if (this.aiTyping || this.aiGenerating) return
      this.switchSession(index)
    },

    /** 处理会话操作 */
    handleSessionAction(action) {
      if (this.aiTyping || this.aiGenerating) return
      action()
    },

    /** 转换消息内容 */
    transformMessage(message) {
      if (!message) return message;
      
      // 处理流式输出中的think标签
      let isInThinkBlock = false;
      return message.split('\n').map(line => {
        // 检查是否包含开始标签
        if (line.includes('<think>')) {
          isInThinkBlock = true;
          // 替换开始标签并添加引用符号
          return '> ' + line.replace('<think>', '');
        }
        // 检查是否包含结束标签
        if (line.includes('</think>')) {
          isInThinkBlock = false;
          // 替换结束标签
          return '> ' + line.replace('</think>', '');
        }
        // 如果在think块内，添加引用符号
        if (isInThinkBlock) {
          return '> ' + line;
        }
        return line;
      }).join('\n');
    }
  },
  beforeDestroy() {
    // 组件销毁前中止所有请求
    if (this.currentRequestId) {
      stopGeneration(this.currentRequestId).catch(console.error)
    }
    if (this.abortController) {
      this.abortController.abort()
    }
  }
}
</script>

<style>
  .v-md-editor {
    background: transparent !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
  }

  .github-markdown-body {
    background: transparent !important;
    padding: 8px !important;
    margin: 0 !important;
    display: inline-grid;
  }

  .github-markdown-body:has(> p:only-child) {
    display: inline-block;
    padding: 2px 4px !important;
  }

  .github-markdown-body:has(> p:only-child) p {
    margin: 0 !important;
  }

  /* 调整段落和列表的间距 */
  .github-markdown-body p {
    margin: 8px 0 !important;
    line-height: 1.6 !important;
    display: inline-block;
  }

  /* 调整列表样式 */
  .github-markdown-body ul,
  .github-markdown-body ol {
    display: grid;
    margin: 0 !important;
    padding-left: 34px !important;
    list-style-type: none !important;
  }

  .github-markdown-body ul {
    list-style-type: disc !important;
  }

  .github-markdown-body li {
    display: list-item;
    line-height: 1.7 !important;
    margin: 0px 0 !important;
    padding: 0 !important;
  }

  /* 调整列表内的段落间距 */
  .github-markdown-body li > p {
    margin: 8px 0 !important;
    line-height: 1.4 !important;
  }

  /* 确保嵌套列表的间距合适 */
  .github-markdown-body li > ul,
  .github-markdown-body li > ol {
    margin: 8px 0 !important;
    padding-left: 24px!important;
  }

  /* 调整列表项内容对齐 */
  .github-markdown-body li > * {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
  }

  /* 确保代码块在列表中正确对齐 */
  .github-markdown-body li pre {
    margin-top: 10px 0 !important;
  }

  /* 调整列表中的链接和内联代码对齐 */
  .github-markdown-body li code,
  .github-markdown-body li a {
    vertical-align: baseline !important;
  }

  /* 调整列表项的内容间距 */
  .github-markdown-body li > p:first-child {
    margin-top: 0 !important;
  }

  .github-markdown-body li > p:last-child {
    margin-bottom: 0 !important;
  }

  /* 调整嵌套列表的缩进 */
  .github-markdown-body li > ul,
  .github-markdown-body li > ol {
    padding-left: 20px !important;
  }

  /* 调整代码块样式 */
  .github-markdown-body pre {
    margin: 8px 0 !important;
    border-radius: 4px !important;
  }

  .github-markdown-body pre code {
    font-size: 14px !important;
    line-height: 1.5 !important;
  }

  /* 调整内联代码样式 */
  .github-markdown-body code {
    padding: 2px 4px !important;
    font-size: 14px !important;
    border-radius: 3px !important;
  }

  /* 调整标题样式 */
  .github-markdown-body h1,
  .github-markdown-body h2,
  .github-markdown-body h3,
  .github-markdown-body h4,
  .github-markdown-body h5,
  .github-markdown-body h6 {
    margin: 16px 0 8px 0 !important;
    line-height: 1.4 !important;
  }

  /* 调整表格样式 */
  .github-markdown-body table {
    margin: 8px 0 !important;
    display: block !important;
    overflow-x: auto !important;
  }

  /* 调整引用块样式 */
  .github-markdown-body blockquote {
    margin: 8px 0 !important;
    padding: 0 12px !important;
    color: #666 !important;
    border-left: 3px solid #f1f1f1 !important;
    display: inline-grid;
  }

  .github-markdown-body div[class*=v-md-pre-wrapper-] {
    position: relative;
    background-color: #f6f8fa;
    display: flex;
    margin: 4px 0;
    border-radius: 8px;
  }
</style>

<style lang="scss">
@import './index.scss';

.chat-messages {
  .message-item {
    &.assistant {
      background: #f5f7fa;
      .message-content {
        white-space: pre-wrap;
        word-break: break-word;
      }
    }
  }
}
</style>
